next up previous
Next: C layerdemo.c Up: Programming X Overlay Windows Previous: A XLayerUtil.h

B XLayerUtil.c

#include <stdio.h>
#include <stdlib.h>
#include "XLayerUtil.h"

static Bool layersRead;
static Atom overlayVisualsAtom;
static OverlayInfo **overlayInfoPerScreen;
static unsigned long *numOverlaysPerScreen;

XLayerVisualInfo *
XGetLayerVisualInfo(display, lvinfo_mask, lvinfo_template, nitems_return)
   Display *display;
   long lvinfo_mask;
   XLayerVisualInfo *lvinfo_template;
   int *nitems_return;
{
   XVisualInfo *vinfo;
   XLayerVisualInfo *layerInfo;
   Window root;
   Status status;
   Atom actualType;
   unsigned long sizeData, bytesLeft;
   int actualFormat, numVisuals, numScreens, count, i, j;

   vinfo = XGetVisualInfo(display, lvinfo_mask&VisualAllMask,
      &lvinfo_template->vinfo, nitems_return);
   if(vinfo == NULL)
      return NULL;
   numVisuals = *nitems_return;
   if(layersRead == False) {
      overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True);
      if(overlayVisualsAtom != None) {
         numScreens = ScreenCount(display);
         overlayInfoPerScreen = (OverlayInfo**) malloc(numScreens*sizeof(OverlayInfo*));
         numOverlaysPerScreen = (unsigned long*) malloc(numScreens*sizeof(unsigned long));
         if(overlayInfoPerScreen != NULL && numOverlaysPerScreen != NULL) {
            for(i=0; i<numScreens; i++) {
               root = RootWindow(display, i);
               status = XGetWindowProperty(display, root, overlayVisualsAtom,
                  0L, (long)10000, False, overlayVisualsAtom, &actualType, &actualFormat,
                  &sizeData, &bytesLeft, (unsigned char**) &overlayInfoPerScreen[i]);
               if(status!=Success || actualType!=overlayVisualsAtom ||
                 actualFormat!=32 || sizeData<4)
                  numOverlaysPerScreen[i] = 0;
               else
                  /* four 32-bit quantities per SERVER_OVERLAY_VISUALS entry */
                  numOverlaysPerScreen[i] = sizeData / 4;
            }
            layersRead = True;
         } else {
            if(overlayInfoPerScreen != NULL) free(overlayInfoPerScreen);
            if(numOverlaysPerScreen != NULL) free(numOverlaysPerScreen);
         }
      }
   }
   layerInfo = (XLayerVisualInfo*) malloc(numVisuals * sizeof(XLayerVisualInfo));
   if(layerInfo == NULL) {
      XFree(vinfo);
      return NULL;
   }
   count = 0;
   for(i=0; i<numVisuals; i++) {
      XVisualInfo *pVinfo;
      int screen;
      OverlayInfo *overlayInfo;

      pVinfo = &vinfo[i];
      screen = pVinfo->screen;
      overlayInfo = NULL;
      if(layersRead) {
         for(j=0; j<numOverlaysPerScreen[screen]; j++)
            if(pVinfo->visualid == overlayInfoPerScreen[screen][j].overlay_visual) {
               overlayInfo = &overlayInfoPerScreen[screen][j];
               break;
            }
      }
      if(lvinfo_mask & VisualLayerMask)
         if(overlayInfo == NULL) {
            if(lvinfo_template->layer != 0) continue;
         } else
            if(lvinfo_template->layer != overlayInfo->layer) continue;
      if(lvinfo_mask & VisualTransparentType)
         if(overlayInfo == NULL) {
            if(lvinfo_template->type != None) continue;
         } else
            if(lvinfo_template->type != overlayInfo->transparent_type) continue;
      if(lvinfo_mask & VisualTransparentValue)
         if(overlayInfo == NULL)
            /* non-overlay visuals have no sense of TransparentValue */
            continue;
         else
            if(lvinfo_template->value != overlayInfo->value) continue;
      layerInfo[count].vinfo = *pVinfo;
      if(overlayInfo == NULL) {
         layerInfo[count].layer = 0;
         layerInfo[count].type = None;
         layerInfo[count].value = 0; /* meaningless */
      } else {
         layerInfo[count].layer = overlayInfo->layer;
         layerInfo[count].type = overlayInfo->transparent_type;
         layerInfo[count].value = overlayInfo->value;
      }
      count++;
   }
   XFree(vinfo);
   *nitems_return = count;
   if(count == 0) {
      XFree(layerInfo);
      return NULL;
   } else
      return layerInfo;
}

Status
XMatchLayerVisualInfo(display, screen, depth, class, layer, lvinfo_return)
Display *display;
int screen, depth, class, layer;
XLayerVisualInfo *lvinfo_return;
{
   XLayerVisualInfo *lvinfo;
   XLayerVisualInfo lvinfoTemplate;
   int nitems;

   lvinfoTemplate.vinfo.screen = screen;
   lvinfoTemplate.vinfo.depth = depth;
   lvinfoTemplate.vinfo.class = class;
   lvinfoTemplate.layer = layer;
   lvinfo = XGetLayerVisualInfo(display,
      VisualScreenMask|VisualDepthMask|VisualClassMask|VisualLayerMask,
      &lvinfoTemplate, &nitems);
   if(lvinfo != NULL && nitems > 0) {
      *lvinfo_return = *lvinfo;
      return 1;
   } else
      return 0;
}



next up previous
Next: C layerdemo.c Up: Programming X Overlay Windows Previous: A XLayerUtil.h



Mark Kilgard
Sun Jan 7 19:28:30 PST 1996